
package com.hlkj.pay.app.merchant.ext.impl.alipay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.date.DatePattern;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantPaymentExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelPaymentAccountContext;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelPaymentCallBackContext;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelPaymentCallBackDto;
import com.hlkj.pay.app.merchant.ext.dto.payment.ChannelPaymentContext;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AliPayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AlipayConfig;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AlipayFundNotifyDto;
import com.hlkj.pay.app.merchant.ext.impl.alipay.handler.AlipayMerchantCommonParamsHandle;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.dto.merchant.MerchantAcctBalanceDto;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.enums.TransferOrderEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessBusinessDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessCertInfoDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.infrastructure.model.payment.MerchantPaymentDO;
import com.hlkj.pay.infrastructure.model.payment.MerchantPaymentDetailDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.MerchantUtils;
import com.hlkj.pay.vo.openapi.order.req.PaymentCommonParamReq;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author HlpayTeam
 * @date 2024/12/16 11:40
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_ALIPAY_FUND)
public class AlipayMerchantPaymentExtPt implements ChannelMerchantPaymentExtPt {

    private final AlipayMerchantCommonParamsHandle alipayMerchantCommonParamsHandle;

    public AliPayAppChannelParams aliPayAppChannelParams(MerchantAppChannelDO merchantAppChannelDO) {
        return JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), AliPayAppChannelParams.class);
    }

    @Override
    public void submitChannelSinglePayment(ChannelPaymentContext channelPayOrderContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPayOrderContext.getProviderChannelConfig(),
                channelPayOrderContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPayOrderContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        // 构造请求参数以调用接口
        AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
        AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();

        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        AliPayAppChannelParams aliPayAppChannelParams = aliPayAppChannelParams(merchantAppChannelDO);
        MerchantPaymentDetailDO merchantPaymentDetailDO = channelPayOrderContext.getMerchantPaymentDetailDO();
        MerchantPaymentDO merchantPaymentDO = channelPayOrderContext.getMerchantPaymentDO();
        // 设置记账账簿id
        model.setOutBizNo(merchantPaymentDetailDO.getDetailPaymentId());
        model.setTransAmount(MerchantUtils.bigDecimalToString2(merchantPaymentDetailDO.getPayAmount()));
        model.setOrderTitle(merchantPaymentDO.getRemark());
        TransferOrderEnums.TRANSFER_ORDER_ENTRY_TYPE transferOrderEntryType = TransferOrderEnums.TRANSFER_ORDER_ENTRY_TYPE.from(merchantPaymentDO.getEntryType());
        model.setProductCode("SINGLE_TRANSFER_NO_PWD");
        model.setBizScene("ENTRUST_TRANSFER");
        Participant payeeInfo = new Participant();
        payeeInfo.setIdentity(merchantPaymentDetailDO.getCardNo());
        switch (transferOrderEntryType) {
            case ALIPAY:
                PaymentCommonParamReq.Extra extra = JsonUtils.parseObject(merchantPaymentDO.getExtra(), PaymentCommonParamReq.Extra.class);
                // 1:通道会员ID 2:通道登录号 3:通道openid 当入账方式为1必填
                switch (extra.getAccountType()) {
                    case 1:
                        payeeInfo.setIdentityType("ALIPAY_USER_ID");
                        break;
                    case 2:
                        payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
                        payeeInfo.setName(merchantPaymentDetailDO.getName());
                        break;
                    case 3:
                        payeeInfo.setIdentityType("ALIPAY_OPEN_ID");
                        break;
                }
                model.setPayeeInfo(payeeInfo);
                model.setBusinessParams("{\"payer_show_name_use_alias\":\"" + extra.isPayerShowName() + "\"}");
                break;
            case BANK:
                payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
                payeeInfo.setName(merchantPaymentDetailDO.getName());
                BankcardExtInfo bankcardExtInfo = new BankcardExtInfo();
                if (merchantPaymentDO.getPayeeType() != null && merchantPaymentDO.getPayeeType() == 2) {
                    bankcardExtInfo.setAccountType("1");
                } else {
                    bankcardExtInfo.setAccountType("2");
                }
                bankcardExtInfo.setBankCode(merchantPaymentDetailDO.getBranchCode());
                bankcardExtInfo.setInstBranchName(merchantPaymentDetailDO.getBranchName());
                bankcardExtInfo.setInstCity(merchantPaymentDetailDO.getCityName());
                bankcardExtInfo.setInstName(merchantPaymentDetailDO.getBankName());
                bankcardExtInfo.setInstProvince(merchantPaymentDetailDO.getProvinceName());
                payeeInfo.setBankcardExtInfo(bankcardExtInfo);
                model.setBusinessParams("{\"withdraw_timeliness\":\"T0\"}");
                break;
        }
        model.setPayeeInfo(payeeInfo);
        Participant payerInfo = new Participant();
        payerInfo.setIdentity(aliPayAppChannelParams.getAccountBookId());
        payerInfo.setIdentityType("ACCOUNT_BOOK_ID");
        payerInfo.setExtInfo("{\"agreement_no\":\"" + aliPayAppChannelParams.getAgreementNo() + "\"}");
        model.setPayerInfo(payerInfo);
        model.setRemark(merchantPaymentDetailDO.getRemark());

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        try {
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            request.setNotifyUrl(channelPayOrderContext.getNotifyUrl());
            log.error("单笔转账接口 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
            log.error("单笔转账接口 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            MerchantPaymentDetailDO updateTransferOrderDO = new MerchantPaymentDetailDO();
            if (response.isSuccess()) {
                updateTransferOrderDO.setThirdPaymentId(response.getOrderId());
                updateTransferOrderDO.setChannelOrderId(response.getPayFundOrderId());
                updateTransferOrderDO.setInsOrderNo(response.getSettleSerialNo());
                if (StringUtils.hasText(response.getTransDate())) {
                    try {
                        updateTransferOrderDO.setSuccessTime(DateUtils.shanghaiDate(response.getTransDate(), "yyyy-MM-dd HH:mm:ss"));
                    }
                    catch (Exception e) {
                        log.error("支付宝转账 返回 时间格式化错误 dateTime:{},message:{}", response.getTransDate(), e.getMessage());
                    }
                }
                // SUCCESS：转账成功； WAIT_PAY：等待支付； CLOSED：订单超时关闭； REFUND：退票； DEALING：转账到银行卡处理中；
                // FAIL：转账失败
                switch (response.getStatus()) {
                    case "SUCCESS":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
                        break;
                    case "CLOSED":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                        break;
                    case "REFUND":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.REFUND.getCode());
                        break;
                    case "FAIL":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                        break;
                    default:
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.DOING.getCode());
                }
                channelPayOrderContext.setUpdateMerchantPaymentDetailDO(updateTransferOrderDO);
            }
            else {
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                channelPayOrderContext.setProcessStatus(false);
                if (StringUtils.hasText(response.getSubMsg())) {
                    channelPayOrderContext.setRemark(response.getSubMsg());
                }
                else {
                    channelPayOrderContext.setRemark(response.getMsg());
                }
            }
        }
        catch (AlipayApiException e) {
            channelPayOrderContext.setProcessStatus(false);
            channelPayOrderContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void queryChannelPayment(ChannelPaymentContext channelPayOrderContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPayOrderContext.getProviderChannelConfig(),
                channelPayOrderContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPayOrderContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        // 构造请求参数以调用接口
        AlipayFundTransCommonQueryRequest request = new AlipayFundTransCommonQueryRequest();
        AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
        MerchantPaymentDO merchantPaymentDO = channelPayOrderContext.getMerchantPaymentDO();
        MerchantPaymentDetailDO merchantPaymentDetailDO = channelPayOrderContext.getMerchantPaymentDetailDO();
        if (CommonEnum.YES_NO_TYPE.YES.getCode().equals(merchantPaymentDO.getPaymentType())) {
            model.setProductCode("FUND_ACCOUNT_BOOK");
            model.setBizScene("SATF_DEPOSIT");
        }
        else {
            model.setProductCode("SINGLE_TRANSFER_NO_PWD");
            model.setBizScene("ENTRUST_TRANSFER");
            model.setOrderId(merchantPaymentDetailDO.getThirdPaymentId());
        }
        // 设置记账账簿id
        model.setOutBizNo(merchantPaymentDetailDO.getDetailPaymentId());
        request.setBizModel(model);
        try {
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            log.error("转账业务单据查询接口 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayFundTransCommonQueryResponse response = alipayClient.certificateExecute(request);
            log.error("转账业务单据查询接口 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            MerchantPaymentDetailDO updateTransferOrderDO = new MerchantPaymentDetailDO();
            if (response.isSuccess()) {
                updateTransferOrderDO.setThirdPaymentId(response.getOrderId());
                updateTransferOrderDO.setChannelOrderId(response.getPayFundOrderId());
                updateTransferOrderDO.setInsOrderNo(response.getSettleSerialNo());
                updateTransferOrderDO.setBankCode(response.getErrorCode());
                updateTransferOrderDO.setRemark(response.getFailReason());
                if (StringUtils.hasText(response.getPayDate())) {
                    try {
                        updateTransferOrderDO.setSuccessTime(DateUtils.shanghaiDate(response.getPayDate(), "yyyy-MM-dd HH:mm:ss"));
                    }
                    catch (Exception e) {
                        log.error("支付宝转账 查询返回 时间格式化错误 dateTime:{},message:{}", response.getPayDate(), e.getMessage());
                    }
                }
                // SUCCESS：转账成功； WAIT_PAY：等待支付； CLOSED：订单超时关闭； REFUND：退票； DEALING：转账到银行卡处理中；
                // FAIL：转账失败
                switch (response.getStatus()) {
                    case "SUCCESS":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
                        break;
                    case "CLOSED":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                        break;
                    case "REFUND":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.REFUND.getCode());
                        break;
                    case "FAIL":
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                        break;
                    default:
                        updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.DOING.getCode());
                }
            }
            else {
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                channelPayOrderContext.setProcessStatus(false);
                if (StringUtils.hasText(response.getSubMsg())) {
                    channelPayOrderContext.setRemark(response.getSubMsg());
                }
                else {
                    channelPayOrderContext.setRemark(response.getMsg());
                }
            }
            channelPayOrderContext.setUpdateMerchantPaymentDetailDO(updateTransferOrderDO);
        }
        catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void queryChannelAccount(ChannelPaymentAccountContext channelPaymentAccountContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPaymentAccountContext.getProviderChannelConfig(),
                channelPaymentAccountContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPaymentAccountContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPaymentAccountContext.setProcessStatus(false);
            return;
        }
        MerchantAppChannelDO merchantAppChannelDO = channelPaymentAccountContext.getMerchantAppChannelDO();
        AliPayAppChannelParams aliPayAppChannelParams = aliPayAppChannelParams(merchantAppChannelDO);
        try {
            // 初始化SDK
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayFundAccountbookQueryRequest request = new AlipayFundAccountbookQueryRequest();
            AlipayFundAccountbookQueryModel model = new AlipayFundAccountbookQueryModel();
            // 设置记账账簿id
            model.setAccountBookId(aliPayAppChannelParams.getAccountBookId());
            // 设置商户会员的唯一标识
            model.setMerchantUserId(merchantAppChannelDO.getSn());
            model.setSceneCode("SATF_FUND_BOOK");
            model.setExtInfo("{\"agreement_no\":\"" + aliPayAppChannelParams.getAgreementNo() + "\"}");
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.error("资金记账本的信息查询 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayFundAccountbookQueryResponse response = alipayClient.certificateExecute(request);
            log.error("资金记账本的信息查询 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            if (response.isSuccess()) {
                MerchantAcctBalanceDto merchantAcctBalanceDto = new MerchantAcctBalanceDto();
                merchantAcctBalanceDto.setBalance(MerchantUtils.stringToBigDecimal(response.getAvailableAmount()));
                merchantAcctBalanceDto.setName(response.getAccountBookId());
                merchantAcctBalanceDto.setExtCardInfo(JsonUtils.toJsonString(response.getExtCardInfo()));
                merchantAcctBalanceDto.setAuthInfo(JsonUtils.toJsonString(response.getAuthInfo()));
                channelPaymentAccountContext.setMerchantAcctBalances(new ArrayList<>() {

                    {
                        add(merchantAcctBalanceDto);
                    }
                });
            }
            else {
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            channelPaymentAccountContext.setProcessStatus(false);
            channelPaymentAccountContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void queryChannelPaymentProof(ChannelPaymentContext channelPayOrderContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPayOrderContext.getProviderChannelConfig(),
                channelPayOrderContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPayOrderContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        AliPayAppChannelParams aliPayAppChannelParams = aliPayAppChannelParams(merchantAppChannelDO);
        try {
            MerchantPaymentDetailDO merchantPaymentDetailDO = channelPayOrderContext.getMerchantPaymentDetailDO();
            MerchantPaymentDO merchantPaymentDO = channelPayOrderContext.getMerchantPaymentDO();
            // 初始化SDK
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            if (!StringUtils.hasText(merchantPaymentDetailDO.getProofId())) {
                // 构造请求参数以调用接口
                AlipayDataBillEreceiptagentApplyRequest request = new AlipayDataBillEreceiptagentApplyRequest();
                AlipayDataBillEreceiptagentApplyModel model = new AlipayDataBillEreceiptagentApplyModel();
                // 设置记账账簿id
                model.setType("FUND_DETAIL");
                model.setKey(merchantPaymentDetailDO.getChannelOrderId());
                model.setAgreementNo(aliPayAppChannelParams.getAgreementNo());
                request.setBizModel(model);
                // 第三方代调用模式下请设置app_auth_token
                // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
                log.info("申请资金业务回单 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
                AlipayDataBillEreceiptagentApplyResponse response = alipayClient.certificateExecute(request);
                log.info("申请资金业务回单 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
                if (response.isSuccess()) {
                    channelPayOrderContext.setFileId(response.getFileId());
                    merchantPaymentDetailDO.setProofId(response.getFileId());
                }
                // channelPayOrderContext.setRemark("支付宝申请电子回单与回单下载需要至少间隔10分钟,请稍后再试");
                Thread.sleep(1 * 1000);
            }
            // 构造请求参数以调用接口
            AlipayDataBillAccountbookereceiptQueryRequest request = new AlipayDataBillAccountbookereceiptQueryRequest();
            AlipayDataBillAccountbookereceiptQueryModel model = new AlipayDataBillAccountbookereceiptQueryModel();
            // 设置记账账簿id
            model.setFileId(merchantPaymentDetailDO.getProofId());
            model.setAgreementNo(aliPayAppChannelParams.getAgreementNo());
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.info("查询资金业务回单申请状态 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayDataBillAccountbookereceiptQueryResponse response = alipayClient.certificateExecute(request);
            log.info("查询资金业务回单申请状态 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            if (response.isSuccess()) {
                channelPayOrderContext.setVoucherFileUrl(response.getDownloadUrl());
            }
            else {
            }
        }
        catch (Exception e) {
            channelPayOrderContext.setProcessStatus(false);
            channelPayOrderContext.setRemark(e.getMessage());
        }
    }

    @Override
    public ChannelPaymentCallBackDto parseCallBackText(ChannelPaymentCallBackContext channelPaymentCallBackContext, HttpServletRequest accessCallBody) {
        // 支付宝 参数解析方法为 parseCallBackTextFix
        return null;
    }

    @Override
    public ChannelPaymentCallBackDto parseCallBackTextFix(HttpServletRequest servletRequest) {
        ChannelPaymentCallBackDto channelPaymentCallBackDto = new ChannelPaymentCallBackDto();
        Map<String, String> parameter = new HashMap<>();
        Map<String, String[]> parameterMap = servletRequest.getParameterMap();
        parameterMap.forEach((key, value) -> {
            parameter.put(key, value[0]);
        });
        String params = parameter.get("biz_content");
        channelPaymentCallBackDto.setRequestParams(JsonUtils.toJsonString(parameter));
        // AlipayFundNotifyDto alipayFundNotifyDto = JsonUtils.parseObject(params,
        // AlipayFundNotifyDto.class);
        AlipayFundNotifyDto.BizContent bizContent = JsonUtils.parseObject(params, AlipayFundNotifyDto.BizContent.class);
        MerchantPaymentDetailDO updateTransferOrderDO = new MerchantPaymentDetailDO();
        updateTransferOrderDO.setDetailPaymentId(bizContent.getOut_biz_no());
        updateTransferOrderDO.setThirdPaymentId(bizContent.getOrder_id());
        updateTransferOrderDO.setChannelOrderId(bizContent.getPay_fund_order_id());
        updateTransferOrderDO.setInsOrderNo(bizContent.getSettle_serial_no());
        updateTransferOrderDO.setBankCode(bizContent.getSub_order_error_code());
        if(StringUtils.hasText(bizContent.getSub_order_fail_reason())){
            updateTransferOrderDO.setRemark(bizContent.getSub_order_fail_reason());
        }else {
            updateTransferOrderDO.setRemark(bizContent.getFail_reason());
        }
        switch (bizContent.getStatus()) {
            case "SUCCESS":
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.SUCCESS.getCode());
                break;
            case "CLOSED":
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                break;
            case "REFUND":
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.REFUND.getCode());
                break;
            case "FAIL":
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.FAIL.getCode());
                break;
            default:
                updateTransferOrderDO.setStatus(MerchantEnum.PROCESS_STATUS.DOING.getCode());
        }
        if (StringUtils.hasText(bizContent.getPay_date())) {
            try {
                updateTransferOrderDO.setSuccessTime(DateUtils.shanghaiDate(bizContent.getPay_date(), "yyyy-MM-dd HH:mm:ss"));
            }
            catch (Exception e) {
                log.error("支付宝转账 查询返回 时间格式化错误 dateTime:{},message:{}", bizContent.getPay_date(), e.getMessage());
            }
        }
        if (StringUtils.hasText(bizContent.getRefund_date())) {
            try {
                updateTransferOrderDO.setRefundSuccessTime(DateUtils.shanghaiDate(bizContent.getRefund_date(), "yyyy-MM-dd HH:mm:ss"));
            }
            catch (Exception e) {
                log.error("支付宝转账 查询返回 时间格式化错误 dateTime:{},message:{}", bizContent.getRefund_date(), e.getMessage());
            }
        }
        channelPaymentCallBackDto.setMerchantPaymentDetailDO(updateTransferOrderDO);
        return channelPaymentCallBackDto;
    }

    @Override
    public String processCallBack(MerchantAppChannelDO merchantAppChannelDO, CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "success";
        }
        return "fail";
    }

    @Override
    public Boolean verify(ProviderChannelConfigDO providerChannelConfigDO, MerchantAppChannelDO merchantAppChannelDO, String accessCallBody) {
        AliPayAppChannelParams aliPayAppChannelParams = aliPayAppChannelParams(merchantAppChannelDO);

        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(providerChannelConfigDO, true);
        AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
        try {
            String charset = "utf-8";
            String sign_type = "RSA2";
            String alipayPublicCertPath = alipayConfig.getAlipayPublicCertPath();
            // 编码格式
            Map<String, String> map = JsonUtils.parseObject(accessCallBody, Map.class);
            // 验签方法
            return AlipaySignature.rsaCertCheckV1(map, alipayPublicCertPath, charset, sign_type);
        }
        catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public void notifyChannel(ChannelPaymentContext channelPaymentContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPaymentContext.getProviderChannelConfig(),
                channelPaymentContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPaymentContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPaymentContext.setProcessStatus(false);
            return;
        }
        MerchantPaymentDO merchantPaymentDO = channelPaymentContext.getMerchantPaymentDO();
        MerchantPaymentDetailDO merchantPaymentDetailDO = channelPaymentContext.getMerchantPaymentDetailDO();
        MerchantAccessDto merchantAccessDto = channelPaymentContext.getMerchantAccessDto();
        try {
            // 初始化SDK
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayEbppIndustryJobPayslipSyncRequest request = new AlipayEbppIndustryJobPayslipSyncRequest();
            AlipayEbppIndustryJobPayslipSyncModel model = new AlipayEbppIndustryJobPayslipSyncModel();
            // 设置外部业务编号
            model.setOutBizNo(merchantPaymentDetailDO.getDetailPaymentId());
            MerchantAccessBusinessDO merchantAccessBusiness = merchantAccessDto.getMerchantAccessBusiness();
            // 设置付款企业名称
            model.setCompanyName(merchantAccessBusiness.getShortName());
            if (merchantAccessDto.getMerchantAccessLicense() != null) {
                // 设置企业信用代码
                model.setCompanyCertNo(merchantAccessDto.getMerchantAccessLicense().getLicenseCode());
            }
            // 设置付款金额
            model.setAmount(MerchantUtils.bigDecimalToString2(merchantPaymentDetailDO.getPayAmount()));
            // 设置付款时间
            model.setSalaryTime(DateUtils.timestampToDate(merchantPaymentDetailDO.getSuccessTime()));
            model.setOrderId(merchantPaymentDetailDO.getThirdPaymentId());
            // 设置用户姓名
            model.setUserName(merchantPaymentDetailDO.getName());
            TransferOrderEnums.TRANSFER_ORDER_ENTRY_TYPE transferOrderEntryType = TransferOrderEnums.TRANSFER_ORDER_ENTRY_TYPE.from(merchantPaymentDO.getEntryType());
            switch (transferOrderEntryType) {
                case ALIPAY:
                    // 设置用户收款渠道
                    model.setChannel("ALIPAY");
                    PaymentCommonParamReq.Extra extra = JsonUtils.parseObject(merchantPaymentDO.getExtra(), PaymentCommonParamReq.Extra.class);
                    // 1:通道会员ID 2:通道登录号 3:通道openid 当入账方式为1必填
                    switch (extra.getAccountType()) {
                        case 1:
                            model.setUserId(merchantPaymentDetailDO.getCardNo());
                            break;
                        case 2:
                            model.setLoginId(merchantPaymentDetailDO.getCardNo());
                            break;
                        case 3:
                            model.setOpenId(merchantPaymentDetailDO.getCardNo());
                            break;
                    }
                    break;
                case BANK:
                    // 设置用户收款渠道
                    model.setChannel("BANK_CARD");
                    // 设置用户收款账号
                    model.setCardNo(merchantPaymentDetailDO.getCardNo());
                    break;
            }
            MerchantAccessCertInfoDO merchantAccessContact = merchantAccessDto.getMerchantAccessContact();
            // 设置客服电话
            model.setContactInfo(merchantAccessContact.getPhone());
            // 设置备注信息
            model.setRemark(merchantPaymentDO.getRemark());
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.info("支付宝就业到账啦明细同步 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayEbppIndustryJobPayslipSyncResponse response = alipayClient.certificateExecute(request);
            log.info("支付宝就业到账啦明细同步 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            if (response.isSuccess()) {
                log.info("支付宝就业到账啦明细同步成功 detailPaymentId:{}", merchantPaymentDetailDO.getDetailPaymentId());
            }
            else {
                log.info("支付宝就业到账啦明细同步失败 detailPaymentId:{}， error:{}", merchantPaymentDetailDO.getDetailPaymentId(), response.getSubMsg());
            }
        }
        catch (Exception e) {
            log.info("支付宝就业到账啦明细同步异常 detailPaymentId:{}， error:{}", merchantPaymentDetailDO.getDetailPaymentId(), e.getMessage(), e);
            channelPaymentContext.setProcessStatus(false);
            channelPaymentContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void submitChannelSingleRecharge(ChannelPaymentContext channelPaymentContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPaymentContext.getProviderChannelConfig(),
                channelPaymentContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPaymentContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPaymentContext.setProcessStatus(false);
            return;
        }
        MerchantAppChannelDO merchantAppChannelDO = channelPaymentContext.getMerchantAppChannelDO();
        AliPayAppChannelParams aliPayAppChannelParams = aliPayAppChannelParams(merchantAppChannelDO);
        try {
            MerchantPaymentDetailDO merchantPaymentDetailDO = channelPaymentContext.getMerchantPaymentDetailDO();
            MerchantPaymentDO merchantPaymentDO = channelPaymentContext.getMerchantPaymentDO();
            // 初始化SDK
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayFundTransPagePayRequest request = new AlipayFundTransPagePayRequest();
            AlipayFundTransPagePayModel model = new AlipayFundTransPagePayModel();
            // 设置记账账簿id
            model.setOutBizNo(merchantPaymentDetailDO.getDetailPaymentId());
            model.setTransAmount(MerchantUtils.bigDecimalToString2(merchantPaymentDetailDO.getPayAmount()));
            model.setProductCode("FUND_ACCOUNT_BOOK");
            model.setBizScene("SATF_DEPOSIT");
            model.setRemark(merchantPaymentDO.getRemark());

            model.setTimeExpire(DateUtils.dateToString(System.currentTimeMillis() + 24 * 60 * 60 * 1000, DatePattern.NORM_DATETIME_MINUTE_PATTERN));
            Participant payeeInfo = new Participant();
            payeeInfo.setIdentity(aliPayAppChannelParams.getAccountBookId());
            payeeInfo.setIdentityType("ACCOUNT_BOOK_ID");
            payeeInfo.setExtInfo("{\"agreement_no\":\"" + aliPayAppChannelParams.getAgreementNo() + "\"}");
            model.setPayeeInfo(payeeInfo);
            // 设置商户会员的唯一标识
            request.setNotifyUrl(channelPaymentContext.getNotifyUrl());
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.info("资金记账本充值 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayFundTransPagePayResponse response = alipayClient.pageExecute(request, "get");
            log.info("资金记账本充值 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            if (response.isSuccess()) {
                channelPaymentContext.setRechargeUrl(response.getBody());
            }
            else {
            }
        }
        catch (Exception e) {
            channelPaymentContext.setProcessStatus(false);
            channelPaymentContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void notifyProofGenerate(ChannelPaymentContext channelPaymentContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelPaymentContext.getProviderChannelConfig(),
                channelPaymentContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelPaymentContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPaymentContext.setProcessStatus(false);
            return;
        }
        MerchantAppChannelDO merchantAppChannelDO = channelPaymentContext.getMerchantAppChannelDO();
        AliPayAppChannelParams aliPayAppChannelParams = aliPayAppChannelParams(merchantAppChannelDO);
        try {
            MerchantPaymentDetailDO merchantPaymentDetailDO = channelPaymentContext.getMerchantPaymentDetailDO();
            MerchantPaymentDO merchantPaymentDO = channelPaymentContext.getMerchantPaymentDO();
            // 初始化SDK
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayDataBillEreceiptagentApplyRequest request = new AlipayDataBillEreceiptagentApplyRequest();
            AlipayDataBillEreceiptagentApplyModel model = new AlipayDataBillEreceiptagentApplyModel();
            // 设置记账账簿id
            model.setType("FUND_DETAIL");
            model.setKey(merchantPaymentDetailDO.getThirdPaymentId());
            model.setAgreementNo(aliPayAppChannelParams.getAgreementNo());
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.info("申请资金业务回单 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayDataBillEreceiptagentApplyResponse response = alipayClient.certificateExecute(request);
            log.info("申请资金业务回单 返回参数:{}", JsonUtils.toJsonStringNotNull(response));
            if (response.isSuccess()) {
                merchantPaymentDetailDO.setProofId(response.getFileId());
            }
            else {
            }
        }
        catch (Exception e) {
            channelPaymentContext.setProcessStatus(false);
            channelPaymentContext.setRemark(e.getMessage());
        }
    }
}
